原始题目:剑指 Offer 53 - II. 0~n-1中缺失的数字 (opens new window)

# 方法一:二分法

因为数组已经排序好了,可以通过二分法去确定,缺失的是哪一个数字。

根据题意,可以将数组分为两部分:

  • 左子数组:nums[i]=inums[i] = i
  • 右子数组:nums[i]inums[i] \neq i;

缺失的数字应当等于右子数组第一个元素的索引。

代码:

public int missingNumber(int[] nums) {
    if (nums[0] != 0){
        return 0;
    }
    if (nums[nums.length-1] != nums.length){
        return nums.length;
    }
    int i = 0, j = nums.length;
    while (i <= j) {
        int mid = (i + j) / 2;
        if (nums[mid] == mid) {
            i = mid + 1;
        } else {
            j = mid - 1;
        }
    }
    return i;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

复杂度分析

  • 时间复杂度O(logN)O(logN):二分法为对数级别复杂度。
  • 空间复杂度O(1)O(1):辅助变量占用常数大小的额外空间。

# 方法二:异或

异或有两条性质:① 0 ^ a = a ; ② a ^ a = 0 。

因为数组中的数字都是唯一的,将数组内的元素全部进行异或操作,然后在和 00 ~ n 进行异或,最后会只剩下那个不在数组中的数字。

public int missingNumber(int[] nums) {
    int xor = 0;
    for (int num : nums) {
        xor ^= num;
    }
    for (int i = 0; i <= nums.length; i++) {
        xor ^= i;
    }
    return xor;
}
1
2
3
4
5
6
7
8
9
10

复杂度分析

  • 时间复杂度O(N)O(N):算法进行 2N2N 次循环。
  • 空间复杂度O(1)O(1):辅助变量占用常数大小的额外空间。
上次更新: 2023/10/15